using System;
using System.Collections;
using System.Reflection;
using CSScriptLibrary;

public class Host
{
    static void Main()
    {
        CallStaticMethod1();
        CallStaticMethod2();
        CallStaticMethod3();
        CallStaticMethod4();
        CallStaticMethod5();
        CallStaticMethodWithExtensions();
        CallInstanceMethod1();
        CallInstanceMethod2();
    }

    static void CallStaticMethod1()
    {
        //AsmHelper allows accessing scripts methods with wild card
        Assembly assembly = CSScript.LoadMethod(
            @"public static void SayHello(string greeting)
              {
                  Console.WriteLine(greeting);
			  }");

        AsmHelper script = new AsmHelper(assembly);
        script.Invoke("*.SayHello", "Hello World!");
    }
    static void CallStaticMethod2()
    {
        //AsmHelper can generate "object FastInvokeDelegate(object instance, params object[] paramters)"
        //delegate which is more convenient to work with.
        FastInvokeDelegate SayHello = new AsmHelper(CSScript.LoadMethod(
            @"public static void SayHello(string greeting)
              {
                  Console.WriteLine(greeting);
			  }"))
              .GetMethodInvoker("*.SayHello", "");

        SayHello(null, "Hello World!");
    }
    
    static void CallStaticMethod3()
    {
        //AsmHelper can generate "object MethodDelegate(params object[] paramters)"
        //delegate which is more convenient to work with.
        //MethodDelegate is just specialized version of FastInvokeDelegate

        var SayHello = new AsmHelper(CSScript.LoadMethod(
            @"public static void SayHello(string greeting)
              {
                  Console.WriteLine(greeting);
			  }"))
              .GetStaticMethod("*.SayHello", "");

        SayHello("Hello World!");
    }

    static void CallStaticMethod4()
    {
        //This example is an equivalent of CallStaticMethod5 except 
        //GetStaticMethod() does not pass any parameter, what is equivalent of 
        //GetStaticMethod("*.*");

        var SayHello = new AsmHelper(CSScript.LoadMethod(
            @"public static void SayHello(string greeting)
              {
                  Console.WriteLine(greeting);
			  }"))
              .GetStaticMethod();

        SayHello("Hello World!");
    }
    static void CallStaticMethodWithExtensions()
    {
        //This example is an equivalent of CallStaticMethod4.
        //However you can avoid explicit usage of AsmHelper by using Assembly extension methods

        var SayHello = CSScript.LoadMethod(
            @"public static void SayHello(string greeting)
              {
                  Console.WriteLine(greeting);
			  }").GetStaticMethod();

        SayHello("Hello World!");
    }

    static void CallStaticMethod5()
    {
        //With LoadMethod() you can load code containing multiple methods and you can also
        //specify namespaces

        var script = new AsmHelper(CSScript.LoadMethod(
            @"using System.Windows.Forms;
			 
			 public static void SayHello(string greeting)
			 {
			     MessageBoxSayHello(greeting);
			     ConsoleSayHello(greeting);
		     }
		     
			 public static void MessageBoxSayHello(string greeting)
			 {
			     MessageBox.Show(greeting);
			 }
			 
			 public static void ConsoleSayHello(string greeting)
			 {
			     Console.WriteLine(greeting);
			 }"));

        script.Invoke("*.SayHello", "Hello World!");
    }

    static void CallInstanceMethod1()
    {
        //all classless scripts belong to DynamicClass type generated by the CS-Script engine
        Assembly assembly = CSScript.LoadMethod(
            @"public void SayHello(string greeting)
              {
                  Console.WriteLine(greeting);
			  }");

        AsmHelper script = new AsmHelper(assembly);

        object instance = script.CreateObject("Scripting.DynamicClass"); // or script.CreateObject("*")
        script.InvokeInst(instance, "Scripting.DynamicClass.SayHello", "Hello World!");
    }
    static void CallInstanceMethod2()
    {

        Assembly assembly = CSScript.LoadMethod(
            @"public void SayHello(string greeting)
              {
                  Console.WriteLine(greeting);
			  }");

        AsmHelper script = new AsmHelper(assembly);

        object instance = script.CreateObject("*"); //wild card * can be used as the assembly contains only one class defined
        script.InvokeInst(instance, "*.SayHello", "Hello World!");
    }
}

